import { cloneDeep } from '@/lib/util'
export default class Model {
  constructor (config = {}) {
    this.config = this.formatConfig(config)
    this.init()
  }

  formatConfig (config) {
    const obj = {}
    for (const key in config) {
      obj[key] = {}
      obj[key].type = config[key].type || String
      obj[key].field = config[key].field || key
      obj[key].default = config[key].default !== undefined ? config[key].default : getDefaultValue(config[key].type)
      obj[key].map = config[key].map !== undefined ? config[key].map : null
    }
    return obj
  }

  init () {
  }

  // 接口数据转换为本地数据
  fromData (data = {}) {
    const config = this.config
    if (Object.keys(config).length === 0) {
      return data
    }
    const result = {}
    for (const key in config) {
      result[key] = getFieldValue(data, config[key])
      switch (complexType(config[key].type)) {
        case 'complexArray':
          result[key] = config[key].type[0].fromDataSet(result[key] || [])
          break
        case 'complexObject':
          result[key] = config[key].type.fromData(result[key])
          break
      }
    }
    return result
  }

  fromDataSet (data = []) {
    return data.map(v => this.fromData(v))
  }

  // 本地数据转换为结构数据
  toData (data = {}) {
    const config = this.config
    if (Object.keys(config).length === 0) {
      return data
    }
    const currentData = cloneDeep(data)
    const result = {}
    for (const key in config) {
      switch (complexType(config[key].type)) {
        case 'complexArray':
          currentData[key] = config[key].type[0].toDataSet(currentData[key])
          break
        case 'complexObject':
          currentData[key] = config[key].type.toData(currentData[key])
          break
      }
      setFieldValue(result, currentData[key], config[key])
    }
    return result
  }

  toDataSet (data = []) {
    return data.map(v => this.toData(v))
  }
}

const getDefaultValue = (type) => {
  switch (type) {
    case String: return ''
    case Number: return 0
    case Boolean: return false
    case Date: return ''
    case Object: return {}
    case Array: return []
    default : return ''
  }
}

const getFieldValue = (data, config) => {
  const keys = config.field.split('.')
  for (let i = 0; i < keys.length; i++) {
    if (i === keys.length - 1 && data[keys[i]]) {
      if (config.map) {
        return config.map[data[keys[i]]]
      }
      if (config.type === Array) { // 针对Array的处理
        return (data[keys[i]] && data[keys[i]].split(',')) || config.default
      }
      return data[keys[i]]
    } else if (isObject(data[keys[i]])) {
      data = data[keys[i]]
    } else {
      return config.default
    }
  }
}
const setFieldValue = (result, data, config) => {
  const map = config.map
  let originData = data
  if (map) {
    for (const key in map) {
      if (map[key] === data) {
        originData = key
      }
    }
  }
  if (config.type === Array) { // 针对Array的处理
    originData = data.join(',')
  }
  const keys = config.field.split('.')
  const len = keys.length - 1
  keys.reduce((cur, key, index) => {
    if (index < len) {
      if (!cur[key]) {
        cur[key] = {}
      }
    }
    if (index === len) {
      cur[key] = originData
    }
    return cur[key]
  }, result)
}
// 判断是否对象
const isObject = (val) => {
  return Object.prototype.toString.call(val) === '[object Object]'
}
// 判断是否复合类型并返回类型
const complexType = (val) => {
  if (val.constructor === Array) {
    if (val[0] instanceof Model) {
      return 'complexArray'
    }
  } else if (val instanceof Model) {
    return 'complexObject'
  } else {
    return false
  }
}
